package arithmetic;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.jupiter.api.Test;

/**
 * Created by jiangfeng on 2017/10/18.
 */
public class TestOutofMemory {

    public static class OOMtest{}

    public static void main(String[] args) throws InterruptedException {
        List a = new ArrayList();
        int count = 0;
        int[] b;
        while (true) {
            a.add(new int[1000]);
            b = new int[10000];
            System.out.println(count++);
            if (count > 10000 && count / 10000 == 0) {

                Thread.sleep(100l);
            }
        }
    }

    /**
     * java.lang.OutOfMemoryError: Java heap space
     * jvm -Xmx:xms10m -xms10m
     */
    @Test
    public void testOutOfMemery() {
        String str = "阿斯顿发送到";
        // 或者new一个大对象
        byte[] bytes = new byte[100*1024*1024];//100m的大对象

        while (true) {
            str += str + new Random().nextInt(11111111) + new Random().nextInt(22222222);
            str.intern();
        }

     }

    /**
     * StackOverflowError
     */
    @Test
     public void testOverStack(){
        int i =0;
        overStack(i);
     }

     private void overStack(int i){
         System.out.println(i);
        overStack(++i);
     }



    /**
     *-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
     * Exception in thread "main" java.lang.outofMemoryError:GC overhead limit exceeded
     */
    @Test
    public void testLimitExceeded(){
        int i=0;
        ArrayList a = new ArrayList();
        try {
            while (true){
                a.add(String.valueOf(i++));
            }
        }catch (Throwable e){ //此处用 Exception无效
            System.out.println(i);
            e.printStackTrace();
            throw e;
        }
     }

    /**
     *
     * java.lang.OutOfMemoryError:unable to create new native thread
     */
    @Test
    public void testNativeThread(){
        for (int i = 0;  ; i++) {
            new Thread(()->{
                try {
                    Thread.sleep(Integer.MAX_VALUE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },""+i).start();
        }
    }

    /**
     * 需引入cglib包
     * -XX:MetaspaceSize=18m -XX:MaxMetaspaceSize=18m
     * java.Lang.OutofMemoryError:Metaspace
     *  Metaspace 空间溢出，我们不断生成类往元空间灌, 类占据的空间总是会超过Metaspace指定的空间大小的
     *  引入cjLib包
     */
    @Test
    public void testMetaspace(){
        int i = 0;
        try {
            for (i = 0; ; i++) {
                Enhancer enhancer =new Enhancer();
                enhancer.setSuperclass(OOMtest.class);
                enhancer.setUseCache(false);
                enhancer.setCallback(new MethodInterceptor() {
                    @Override
                    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                        return proxy.invokeSuper(obj,args);
                    }
                });
                enhancer.create();
            }
        } catch (Throwable e) {
            System.out.println("e" + i);
            throw e;
        }

    }

}
